using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ComponentAce.Compression.Libs.zlib;
using ItProject.Andir.Cryptography;
using EMISecurity.SymmetricCryptography.CryptoManaged;
using OpenMcdf;

namespace Gameshield
{
    public class GameshieldLicenseDecrypter
    {
        public static void repackLicense(String licFile, String encryptedDataFile)
        {

            CompoundFile cf = new CompoundFile(licFile,UpdateMode.Update,true,true);
            
            CFStream cfs = cf.RootStorage.GetStream("Basic");
            cfs.SetData(File.ReadAllBytes(encryptedDataFile));
            cf.Commit();
            cf.Close();
        }
        public static MemoryStream decryptLicense(String licFile, String password)
        {
            byte[] data = null;
            try
            {
                CompoundFile cf = new CompoundFile(licFile);
                CFStream cfs = cf.RootStorage.GetStream("Basic");
                data = cfs.GetData();
            }
            catch (CFFileFormatException e)
            {
                FileStream fs = new FileInfo(licFile).OpenRead();
                data = new byte[fs.Length];
                fs.Read(data, 0, data.Length);
            }
            catch (Exception ex)
            { }
            Haval256 haval = new Haval256(HavalPassCount.Pass5);
            haval.Initialize();
            byte[] hash = haval.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(password));

            BlowfishCBC cbc = new BlowfishCBC(hash, 0, hash.Length);

            BlowfishECB ecb = new BlowfishECB(hash, 0, hash.Length);
            byte[] iv = new byte[8];

            ecb.Encrypt(new byte[8] { 255, 255, 255, 255, 255, 255, 255, 255 }, 0, iv, 0, 8);

            cbc.SetIV(iv, 0);
            byte[] decryptedData = new byte[data.Length * 5];
            int size = cbc.Decrypt(data.ToArray(), 0, decryptedData, 0, (int)data.Length);

            int bdata = 0;
            int stopByte = -1;
            MemoryStream ms = new MemoryStream(decryptedData, 0, size);
            ZInputStream inZStream = new ZInputStream(ms);
            MemoryStream decompressed = new MemoryStream();
            while (stopByte != (bdata = inZStream.Read()))
            {
                byte _dataByte = (byte)bdata;
                decompressed.WriteByte(_dataByte);
            }

            inZStream.Close();

            System.IO.FileStream _FileStream = new System.IO.FileStream(@"C:\foo.dat", System.IO.FileMode.Create, System.IO.FileAccess.Write);
            // Writes a block of bytes to this stream using data from a byte array.
            _FileStream.Write(decompressed.ToArray(), 0, decompressed.ToArray().Length);
            // close file stream
            _FileStream.Close();

            return decompressed;
        }
        public static void CopyStream(ZInputStream input, System.IO.Stream output)
        {
            byte[] buffer = new byte[1];
            int len;
            while ((len = input.Read(buffer, 0, 1)) > 0)
            {
                output.Write(buffer, 0, len);
            }
            output.Flush();
        }
    }
}
